package com.zemb.flxwear.UI.Activity;

import android.app.FragmentTransaction;
import android.bluetooth.BluetoothGatt;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.PersistableBundle;
import android.os.PowerManager;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.data.BleScanState;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.zemb.flxwear.Bean.ReportItem;
import com.zemb.flxwear.R;
import com.zemb.flxwear.TaskQueue.BaseTask;
import com.zemb.flxwear.TaskQueue.TaskQueue;
import com.zemb.flxwear.TaskQueue.TaskThread;
import com.zemb.flxwear.UI.Fragment.BaseFragment;
import com.zemb.flxwear.UI.Fragment.BloodFourCategoryFragment;
import com.zemb.flxwear.UI.Fragment.BloodOxygenFragment;
import com.zemb.flxwear.UI.Fragment.BloodPressureFragment;
import com.zemb.flxwear.UI.Fragment.ConnectFragment;
import com.zemb.flxwear.UI.Fragment.ECGFragment;
import com.zemb.flxwear.Utils.DeviceUtils;
import com.zemb.flxwear.Utils.LogUtils;
import com.zemb.flxwear.Utils.VoicePlayUtils;

import java.io.Serializable;
import java.util.List;

public class MeasureActivity extends AppCompatActivity {

    DeviceUtils.Category category;

    TaskThread taskThread;
    PowerManager powerManager;
    PowerManager.WakeLock wakeLock;
    //a thread
    Handler handler;

    boolean isConnect = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_measure);
        initData();
        initView();
        initBle();
    }


    private BloodOxygenFragment bloodOxygenFragment;
    private BloodPressureFragment bloodPressureFragment;
    private ECGFragment ecgFragment;
    private BloodFourCategoryFragment bloodFourCategoryFragment;
    private ConnectFragment connectFragment;

    private final BleGattCallback bleGattCallback = new BleGattCallback() {
        @Override
        public void onStartConnect() {
            if(currentFragment!=null&&currentFragment.isAdded()){
                currentFragment.onStartConnectDevice();
            }
        }

        @Override
        public void onConnectFail(BleDevice bleDevice, BleException exception) {
            isConnect = false;
            if(currentFragment!=null&&currentFragment.isAdded()){
                currentFragment.onDeviceConnectFail(bleDevice,exception);
            }


        }

        @Override
        public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
            setCurrentDevice(bleDevice);
            isConnect = false;
            if(currentFragment!=null&&currentFragment.isAdded()){
                currentFragment.onDeviceConnect(bleDevice);
            }
        }

        @Override
        public void onDisConnected(boolean isActiveDisConnected, BleDevice currentDevice, BluetoothGatt gatt, int status) {
            if(currentFragment!=null&&currentFragment.isAdded()){
                currentFragment.onDeviceDisConnected(currentDevice);
            }
        }
    };
    private BleDevice currentDevice;

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        LogUtils.PrintLog("onSaveInstanceState");
    }

    public void setCurrentDevice(BleDevice currentDevice) {
        if ((currentDevice.getName() + "").contains(DeviceUtils.BLOOD_PRESSURE)) {
            //血压设备
            DeviceUtils.putUUId(DeviceUtils.Category.BLOOD_PRESSURE,currentDevice.getMac());

        } else if ((currentDevice.getName() + "").contains(DeviceUtils.ECG)) {
            //心电设备
            DeviceUtils.putUUId(DeviceUtils.Category.ECG,currentDevice.getMac());
        } else if ((currentDevice.getName() + "").contains(DeviceUtils.BLOOD_OXYGEN)) {
            //血氧设备
            DeviceUtils.putUUId(DeviceUtils.Category.BLOOD_OXYGEN,currentDevice.getMac());

        } else if ((currentDevice.getName() + "").contains(DeviceUtils.BLOOD_FOUR_CATEGORY)) {
            //四合一设备
            DeviceUtils.putUUId(DeviceUtils.Category.BLOOD_SUGAR,currentDevice.getMac());
        }
        this.currentDevice = currentDevice;
    }

    public BleDevice getCurrentDevice() {

        return currentDevice;
    }

    public void initFragment() {
        bloodOxygenFragment = new BloodOxygenFragment();
        bloodPressureFragment = new BloodPressureFragment();
        ecgFragment = new ECGFragment();
        bloodFourCategoryFragment = new BloodFourCategoryFragment();
        connectFragment = new ConnectFragment();

    }

    public void initView() {
        if (category != null) {
            switch (category) {
                //血氧
                case BLOOD_OXYGEN:
                    switchFragment(DeviceUtils.UIType.BLOOD_OXYGEN);
                    break;
                //血压
                case BLOOD_PRESSURE:
                    switchFragment(DeviceUtils.UIType.BLOOD_PRESSURE);
                    break;
                //心电
                case ECG:
                    switchFragment(DeviceUtils.UIType.ECG);
                    break;
                case BLOOD_KETONE:
                case CHOLESTEROL:
                case URIC_ACID:
                case BLOOD_SUGAR:
                    switchFragment(DeviceUtils.UIType.BLOOD_FOUR_CATEGORY);
                    break;
                default:
                    break;
            }

        } else {
            switchFragment(DeviceUtils.UIType.CONNECT);
        }

    }

    private BaseFragment currentFragment;

    public void initData() {
        VoicePlayUtils.getInstance().onCreate(this);
        category = (DeviceUtils.Category) getIntent().getSerializableExtra("tag");
        if (category != null) {
            switch (category) {
                case ALL:
                    initTaskQueue();
                    break;
            }
        }
        initFragment();
    }

    public void initBle() {
        BleManager.getInstance().init(getApplication());
        //提示设备不支持蓝牙并且三秒后关闭应用
        if (!BleManager.getInstance().isSupportBle()) {
            //提示设备不支持蓝牙并且三秒后关闭应用
            Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    finish();
                }
            }, 3000);
            return;
        }
        BleManager.getInstance().enableBluetooth();
        BleManager.getInstance()
                .setMaxConnectCount(1)
                .enableLog(true)
                .setReConnectCount(0, 5000)
                .setSplitWriteNum(20)
                //设置连接超时时间 120s
                .setConnectOverTime(10000)
                //设置操作超时时间 5s
                .setOperateTimeout(5000);

    }

    public void ScanDevice(BleScanRuleConfig config, BleScanCallback bleScanCallback) {
        BleManager.getInstance().initScanRule(config);
        BleManager.getInstance().scan(bleScanCallback);
    }

    public void ConnectDevice(BleDevice currentDevice) {
        if(isConnect){
            return;
        }
        isConnect = true;
        BleManager.getInstance().connect(currentDevice, bleGattCallback);
    }

    public void ConnectDevice(String mac) {
        if (isConnect) {
            return;
        }
        isConnect = true;
        BleManager.getInstance().connect(mac, bleGattCallback);
    }


    public void CancelScan() {
        if (BleManager.getInstance().getScanSate() == BleScanState.STATE_SCANNING) {
            BleManager.getInstance().cancelScan();
        }
    }

    public void SetNotify(BleDevice currentDevice, String uuid_servers, String uuid_notify, BleNotifyCallback notifyCallback) {
        BleManager.getInstance().notify(currentDevice, uuid_servers, uuid_notify, notifyCallback);
    }

    public void StopNotify(BleDevice currentDevice, String uuid_servers, String uuid_notify) {
        BleManager.getInstance().stopNotify(currentDevice, uuid_servers, uuid_notify);
    }

    public void disconnectDevice(BleDevice currentDevice) {
        BleManager.getInstance().disconnect(currentDevice);
        currentDevice = null;
    }

    /**
     * 切换fragment
     *
     * @param uiType fragment类型
     */
    public void switchFragment(DeviceUtils.UIType uiType) {
        switchFragment(uiType, null, false);

    }

    /**
     * 切换fragment
     *
     * @param uiType   fragment类型
     * @param category 项目类别
     * @param isAuto   是否自动测量
     */
    public void switchFragment(DeviceUtils.UIType uiType, DeviceUtils.Category category, boolean isAuto) {
        if(category!= null){
            this.category = category;
        }
        Bundle bundle = new Bundle();
        bundle.putSerializable("category", category);
        bundle.putBoolean("isAuto", isAuto);
        switch (uiType) {
            //血压
            case BLOOD_PRESSURE:
                //切换到血压测量界面
                LogUtils.PrintLog("切换到血压测量界面");
                switchFragment(bloodPressureFragment, bundle);
                break;
            //血液四项
            case BLOOD_FOUR_CATEGORY:
                //切换到血糖测量界面
                LogUtils.PrintLog("切换到血糖测量界面");
                switchFragment(bloodFourCategoryFragment, bundle);
                break;
            //血氧
            case BLOOD_OXYGEN:
                //切换到血氧测量界面
                LogUtils.PrintLog("切换到血氧测量界面");
                switchFragment(bloodOxygenFragment, bundle);
                break;
            //心电
            case ECG:
                //切换到心电测量界面
                LogUtils.PrintLog("切换到心电测量界面");
                switchFragment(ecgFragment, bundle);
                break;
            //设备
            case CONNECT:
                //切换到设备连接界面
                LogUtils.PrintLog("切换到设备连接界面");
                switchFragment(connectFragment, bundle);
                break;

        }

    }

    /**
     * 切换fragment
     *
     * @param targetFragment 目标fragment
     * @param bundle         传递的参数
     */
    private void switchFragment(BaseFragment targetFragment, Bundle bundle) {
        LogUtils.PrintLog("切换fragment"+targetFragment.getClass().getSimpleName());
        //已经显示就不切换
        FragmentTransaction transaction = getFragmentManager().beginTransaction();

        if (currentFragment == targetFragment){
            currentFragment.restart();
        }

        //没有添加则先完成添加再显示
        targetFragment.setBundleData(bundle);
        if (!targetFragment.isAdded()) {
           // targetFragment.setArguments(bundle);

            if (currentFragment == null) {
                transaction
                        .add(R.id.fragment_container, targetFragment)
                        .commitAllowingStateLoss();
            } else {
                transaction
                        .hide(currentFragment)
                        .add(R.id.fragment_container, targetFragment)
                        .commitAllowingStateLoss();
            }
            LogUtils.PrintLog("第一次添加 ");

        } else {
            //都添加了就直接隐藏当前fragment，显示目标fragment
            transaction
                    .hide(currentFragment)
                    .show(targetFragment)
                    .commitAllowingStateLoss();
            LogUtils.PrintLog("完成切换");
        }
        currentFragment = targetFragment;
    }


    public DeviceUtils.Category getMeasureTag() {

        return category==null?DeviceUtils.Category.BLOOD_PRESSURE:category;
    }

    public void initTaskQueue() {

        handler = new Handler();
        //create a thread;
        taskThread = new TaskThread(new TaskQueue.OnTaskFinishedListener() {
            @Override
            public void onTaskFinished() {

            }

            @Override
            public void onTaskFailed() {

            }

            @Override
            public void onTaskProgress(int progress) {

            }

            @Override
            public void onAllFailed() {
               runOnUiThread(new Runnable() {
                   @Override
                   public void run() {
                       Toast.makeText(MeasureActivity.this, MeasureActivity.this.getResources().getText(R.string.measure_error), Toast.LENGTH_SHORT).show();
                        finish();
                   }
               });
            }

            @Override
            public void onTaskStart(BaseTask task) {
                LogUtils.PrintLog("开始任务");
                if (task.getType() == DeviceUtils.Category.REPORT) {
                    Intent intent = new Intent(MeasureActivity.this, MedicalReportActivity.class);
                    List<ReportItem> reportItems = taskThread.getResult();
                    intent.putExtra("reportItems", (Serializable) reportItems);
                    startActivity(intent);
                    finish();
                } else {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            switch (task.getType()) {
                                case BLOOD_KETONE:
                                    switchFragment(DeviceUtils.UIType.BLOOD_FOUR_CATEGORY, DeviceUtils.Category.BLOOD_KETONE, true);
                                    break;
                                case URIC_ACID:
                                    switchFragment(DeviceUtils.UIType.BLOOD_FOUR_CATEGORY, DeviceUtils.Category.URIC_ACID, true);
                                    break;
                                case BLOOD_SUGAR:
                                    switchFragment(DeviceUtils.UIType.BLOOD_FOUR_CATEGORY, DeviceUtils.Category.BLOOD_SUGAR, true);
                                    break;
                                case CHOLESTEROL:
                                    switchFragment(DeviceUtils.UIType.BLOOD_FOUR_CATEGORY, DeviceUtils.Category.CHOLESTEROL, true);
                                    break;
                                case BLOOD_OXYGEN:
                                    switchFragment(DeviceUtils.UIType.BLOOD_OXYGEN, DeviceUtils.Category.BLOOD_OXYGEN, true);
                                    break;
                                case BLOOD_PRESSURE:
                                    switchFragment(DeviceUtils.UIType.BLOOD_PRESSURE, DeviceUtils.Category.BLOOD_PRESSURE, true);
                                    break;
                                case ECG:
                                    switchFragment(DeviceUtils.UIType.ECG, DeviceUtils.Category.ECG, true);
                                    break;
                            }
                        }
                    });
                }
            }
        });
//        taskThread.addTask(new BaseTask(DeviceUtils.Category.BLOOD_PRESSURE));
//        taskThread.addTask(new BaseTask(DeviceUtils.Category.BLOOD_OXYGEN));
        taskThread.addTask(new BaseTask(DeviceUtils.Category.ECG));
        taskThread.addTask(new BaseTask(DeviceUtils.Category.BLOOD_SUGAR));
        taskThread.addTask(new BaseTask(DeviceUtils.Category.BLOOD_KETONE));
        taskThread.addTask(new BaseTask(DeviceUtils.Category.CHOLESTEROL));
        taskThread.addTask(new BaseTask(DeviceUtils.Category.URIC_ACID));
        taskThread.addTask(new BaseTask(DeviceUtils.Category.REPORT));
        //异步等待3秒钟后开始执行任务
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                taskThread.start();
            }
        }, 3000);
    }


    public void finishTask(ReportItem item) {
        taskThread.finishTask(item);
    }

    public void failTask() {
        taskThread.failTask();
    }
    public void passTask() {
        taskThread.passTask();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (taskThread != null) {
            LogUtils.PrintLog("停止任务");
            taskThread.stopThread();

        }
        BleManager.getInstance().disconnectAllDevice();
    }

    @Override
    public void onBackPressed() {
        if(currentFragment!=null){
            if(!currentFragment.canPressBack){
                return;
            }
        }
        super.onBackPressed();
    }




    public void sendDeviceData(byte[] data, String service_uuid, String write_uuid, BleWriteCallback callback) {
        BleManager.getInstance().write(
                currentDevice,
                service_uuid,
                write_uuid,
                data,
                callback);

    }
    public void wakeLock(){
        if (wakeLock == null) {
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, MeasureActivity.class.getName());
            wakeLock.acquire();
        }
    }


    public void releaseWakeLock() {
        if (wakeLock != null) {
            wakeLock.release();
            wakeLock = null;
        }
    }
    public List<BleDevice> getAllDevice(){
      return   BleManager.getInstance().getAllConnectedDevice();
    }



}